#include <linux/init.h>
#include <linux/smp.h>
#include <linux/percpu.h>
#include <linux/sched/task.h>
#include <linux/bug.h>

/*
 * For the hotplug case we keep the task structs around and reuse
 * them.
 */
static DEFINE_PER_CPU(struct task_struct *, idle_threads) = NULL;

/**
 * idle_init - Initialize the idle thread for a cpu
 * @cpu:	The cpu for which the idle thread should be initialized
 *
 * Creates the thread if it does not exist.
 */
static inline void idle_init(unsigned int cpu)
{
    struct task_struct *tsk = per_cpu(idle_threads, cpu);

    if (!tsk)
    {
        fork_idle(cpu, &tsk);

        if (tsk == NULL)
        {
            pr_err("SMP: fork_idle() failed for CPU %u\n", cpu);
        }
        else
        {
            per_cpu(idle_threads, cpu) = tsk;
        }
    }
}

struct task_struct *idle_thread_get(unsigned int cpu)
{
    struct task_struct *tsk = per_cpu(idle_threads, cpu);

    return tsk;
}

/**
 * idle_threads_init - Initialize idle threads for all cpus
 */
void __init idle_threads_init(void)
{
    unsigned int cpu, boot_cpu;

    boot_cpu = smp_processor_id();

    for_each_possible_cpu(cpu)
    {
        if (cpu != boot_cpu)
            idle_init(cpu);
    }
}
